import Collapse from "components/Markdown/Collapse"
import Code from "components/Markdown/Code"
import Warning from "components/Markdown/Warning"
import Info from "components/Markdown/Info"

export const meta = {
  title: "Reading Data (JavaScript)",
  position: 50,
  technology: "node",
  technologyOrder: 1,
  articleGroup: "Reading Data",
}

## Overview

The Prisma client is based on the operations defined in the GraphQL schema of your Prisma API. For _reading_ data, it basically _mirrors_ the [GraphQL queries](qwe1) of your Prisma service.

For this page, we'll assume your Prisma API is based on the following [datamodel](knul):

```graphql
type Link {
  id: ID! @unique
  createdAt: DateTime!
  description: String!
  url: String!
  postedBy: User
  votes: [Vote!]!
}

type User {
  id: ID! @unique
  name: String!
  email: String! @unique
  password: String!
  links: [Link!]!
  votes: [Vote!]!
}

type Vote {
  id: ID! @unique
  link: Link!
  user: User!
}
```

<Collapse title="View the full generated GraphQL schema & Prisma client">

- You can view what the generated GraphQL schema for the API [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.graphql)
- You can view what the generated JavaScript client [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.js).

</Collapse>

Whenever a model is queried using the Prisma client, _all scalar fields_ of that model are fetched. This is true no matter if a single object or a list of objects is queried.

For example, the following query returns all scalar fields of a single `User`:

```js
const user = await prisma.user({ email: "bob@prisma.io" })
```

In this case, the returned `user` object will have four properties (that correspond to the scalar fields of the `User` model): `id`, `name`, `email` and `password`. 

The `links` and `votes` fields are both _relation fields_ and are therefore not included in the query.

Here is an example of fetching a _list_ of `User` objects:

```js
const users = await prisma.users()
```

Similar to the previous query, each object inside the `users` array only has the scalar and no relation fields.

## Fetching single objects

For each model type in your datamodel, there is a method generated in the Prisma client API that allows to fetch single objects of that model. The method is named after the type but starts with a _lowercase_ character. For the sample datamodel from above, the three methods for fetching single `User`, `Link` and `Vote` objects are called `user`, `link` and `vote`.

The input for these functions is an object that has as properties any [unique](knul#unique-scalar-fields) field of the model. This means, for all three methods, the `id` field is accepted (as the corresponding models each have an `id` field annotated as `@unique`). The input object for the `user` method additionaly has an `email` field.

<Collapse title="View the types of the input object for `Link`, `User` and `Vote`">

- View the type of `where` for `Link` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L455)
- View the type of `where` for `User` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L357)
- View the type of `where` for `Vote` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L522)

</Collapse>

### Examples

_Fetch a single vote by its id_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const vote = await prisma.vote({ id: "cjlgpyueg001o0a239d3i07ao" })
```

```graphql
# generated query
query {
  vote(where: {
    id: "cjlgpyueg001o0a239d3i07ao"
  }) {
    id
  }
}
```

</Code>

_Fetch a single user by their email_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const user = await prisma.user({ email: "alice@prisma.io" })
```

```graphql
# generated query
query {
  user(where: {
    email: "alice@prisma.io"
  }) {
    id
  }
}
```

</Code>

## Fetching lists

For each model type in your datamodel, there is a method generated in the Prisma client API that allows to fetch a list of those model objects. The method is named after the model but starts with a _lowercase_ character and uses the _plural_ form. For the sample datamodel from above, the three methods for fetching lists of `User`, `Link` and `Vote` models are called `users`, `links` and `votes`.

The input arugment for these functions is an object that has properties for:

- [Filtering](#basic-filters-for-lists): `where`
- [Ordering](#ordering): `orderBy`
- [Pagination](#pagination): `before`, `after`, `first`, `last`, `skip`

### Examples

_Fetch all links_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma.links()
```

```graphql
# generated query
query {
  links {
    id
    createdAt
    url
    description
  }
}
```

</Code>

_Fetch a list of users_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const users = await prisma.users()
```

```graphql
# generated query
query {
  users {
    id
    name
    email
    password
  }
}
```

</Code>

## Relations

Prisma client has a [fluent API](https://www.sitepoint.com/javascript-like-boss-understanding-fluent-apis/) to query relations in your data graph. Meaning you can simply _chain_ your method calls to navigate the relation properties of the returned models.

<Warning>

This is only possible when retrieving _single_ objects, not for lists. Meaning you can not query relation fields of objects that are returned in a list, e.g.:

```js
// not possible
const result = await prisma
  .users()
  .links()
```

In this example, `users()` already returns a list, so it's not possible to query the `links` relation of each user object inside the list.

</Warning>

### Examples

_Query all the links of a single user_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const linksByUser = await prisma
  .user({ email: "alice@prisma.io" })
  .links()
```

```graphql
query {
  user(where: {
    email: "alice@prisma.io"
  }) {
    links {
      id
      createdAt
      description
      url
    }
  }
}
```

</Code>

 _Query all the votes made by a certain user_:

<Code languages={["JavaScript", "GraphQL"]}>

 ```js
const votesByUser = await prisma
  .user({ email: "alice@prisma.io" })
  .votes()
 ```

 ```graphql
query {
  user(where: {
    email: "alice@prisma.io"
  }) {
    votes {
      id
    }
  }
}
 ```

</Code>

## Using fragments for fine-grained data access

Instead of querying all scalar fields of a model (which is the default behavior), you can specify which fields you'd like retrieve by using the `$fragment` API feature (based on GraphQL). This is useful to exclude large unneeded fields (like BLOB values or huge strings) or to even retrieve relations.

### Examples

_Fetch the `name` and `email` of the users as well the the `description` and `url` of their related links_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const fragment = `
fragment UserWithLinks on User {
  name
  email
  links {
    description
    url
  }
}
`

const userWithPosts = await prisma.users().$fragment(fragment)
```

```graphql
query {
  users {
    ...UserWithLinks
  }
}

fragment UserWithLinks on User {
  name
  email
  links {
    description
    url
  }
}
```

</Code>

## Basic filters for lists

_Basic_ filters let you specify certain criteria to constrain which objects should be returned in a list. The filters are specified in the `where` object of the input argument which is accepted by any list query.

The type of the `where` object depends on the model for which it was generated.

<Collapse title="View the types of `where` for `Link`, `User` and `Vote`">

- View the type of `where` for `Link` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L154)
- View the type of `where` for `User` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L267)
- View the type of `where` for `Vote` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L219)

</Collapse>

It is also possible to _combine_ multiple filters using the `AND` and `OR` fields.

### Examples

_Fetch users that have an `A` in their names_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const usersWithAInName = await prisma
  .users({
    where: {
      name_contains: "A"
    }
  })
```

```graphql
query {
  users(where: {
      name_contains: "A"
  }) {
    id
    name
    email
    password
  }
}
```

</Code>

<Collapse title="Use auto-completion to explore the filter system">

![](https://imgur.com/XwE5z9o.png)

</Collapse>

_Fetch users called `Alice` or `Bob`_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const usersCalledAliceOrBob = await prisma
  .users({
    where: {
      name_in: ["Alice", "Bob"]
    }
  })
```

```graphql
query {
  users(where: {
    name_in: ["Alice", "Bob"]
  }) {
    id
    name
    email
    password
  }
}
```

</Code>

_Fetch links created before December 24, 2018_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const linksBeforeChristmas = await prisma
  .links({
    where: {
      createdAt_lt: "2018-12-24" 
    }
  })
```

```graphql
query {
  links(where: {
    createdAt_lt: "2018-12-24" 
  }) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

> Dates and times in the Prisma client API follow the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard which generally is of the form: `YYYY-MM-DDThh:mm:ss`. [Learn more](knul#datetime).

_Fetch links that have `prisma` **or** `graphql` in their description **and** were created in 2018_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const filteredLinks = await prisma
  .links({
    where: {
      AND: [
        {
          OR: [{
            description_contains: "graphql",
          }, {
            description_contains: "prisma",
          }]
        }, 
        {
          AND: [{
            createdAt_gt: "2017"
          }, {
            createdAt_lt: "2019"
          }]
        }
      ],
    }
  })
```

```graphql
query {
  links(where: {
    OR: [{
      description_contains: "graphql",
    }, {
      description_contains: "prisma",
    }]
    AND: [{ 
      createdAt_lt: "2019"
    }, { 
      createdAt_gt: "2017" 
    }]
  }) {
    id
    description
  }
}
```

</Code>

<Info>

The `AND` filter can actually be omitted since multiple filter criteria are by default combined using a _logical and_. This means the above filter can also be expressed as follows:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const filteredLinks = await prisma
  .links({
    where: {
      OR: [{
        description_contains: "graphql"
      }, {
        description_contains: "prisma"
      }],
      createdAt_gt: "2017",
      createdAt_lt: "2019"
    }
  })
```

```graphql
query {
  links(where: {
    OR: [{
      description_contains: "graphql",
    }, {
      description_contains: "prisma",
    }],
    createdAt_lt: "2019",
    createdAt_gt: "2017" 
  }) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

</Info>


## Relational filters for lists

Relational filters can be used to constrain the returned objects on a relation list field. The types used for filtering are identical to basic filters, the only difference is that the filters are not applied on the first level of the method call but when querying a relation on the second level.

### Examples

<Code languages={["JavaScript", "GraphQL"]}>

```js
const linksByUserBeforeChristmas = await prisma
  .user({ email: "alice@prisma.io" })
  .links({
    where: {
      createdAt_lt: "2017-12-24" 
    }
  })
```

```graphql
query {
 user(where: {
  email: "alice@prisma.io"
 }) {
    links(where: {
      createdAt_lt: "2017-12-24" 
    }) {
      id
      createdAt
      description
      url
  }
 }
}
```

</Code>

## Ordering

When querying a list of model objects, you can order (sort) the list by any scalar field of that model type. Each generated method to query a list of models therefore accepts the `orderBy` field on its input object.

The type of the `orderBy` field depends on the scalar fields of the model for which it was generated.

<Collapse title="View the types of `orderBy` for `Link`, `User` and `Vote`">

- View the type of `orderBy` for `Link` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L114)
- View the type of `orderBy` for `User` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L132)
- View the type of `orderBy` for `Vote` [here](https://github.com/nikolasburk/prisma-client-examples/blob/master/generated/prisma.ts#L125)

</Collapse>

### Examples

_Sort links by their creation date (ascending)_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const sortedLinks = prisma
  .links({
    orderBy: "createdAt_ASC"
  })
```

```graphql
query {
  links(orderBy: createdAt_ASC) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Sort users alphabetically by their names (descending)_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const sortedUsers = prisma
  .users({
    orderBy: "name_DESC"
  })
```

```graphql
query {
  users(orderBy: name_DESC) {
    id
    name
    email
    password
  }
}
```

</Code>


## Pagination

When querying a list of model objects, you can fetch _chunks_ of that list by supplying pagination arguments.

### Seeking forward and backward with `first` and `last`

You can seek forwards or backwards through the objects and supply an optional starting object:

- To seek **forward**, use `first`; specify a starting object with `after`.
- To seek **backward**, use `last`; specify a starting object with `before`.

You **cannot** combine `first` with `before` or `last` with `after`. If you do so in a query, `before`/`after` will simply be ignored and only `first` or `last` is actually applied (at the very beginning or end of the list, depending on which you're using).

Note that you can query for more objects than actually exist in the database without an error message.

### Skipping elements with `skip`

You can also skip an arbitrary amount of objects in whichever direction you are seeking by supplying the `skip` argument:

- When using `first`, `skip` skips objects at the beginning of the list.
- When using `last`, `skip` skips objects from the end of the list.

### Examples

For the following examples, we're assuming a list of exactly 30 objects:

![](https://i.imgur.com/Xh6Qjts.png)

_Query the first 3 links (seeking forward)_:

![](https://i.imgur.com/O1Jj3Z2.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    first: 3
  })
```

```graphql
query {
  links(first: 3) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Query the objects from position 6 to position 10 (seeking forward)_:

![](https://i.imgur.com/PpI5X0X.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    first: 5, 
    skip: 5
  })
```

```graphql
query {
  links(
    first: 5 
    skip: 5
  ) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Query the last 3 objects (seeking backward)_:

![](https://i.imgur.com/pkuYCrV.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    last: 3
  })
```

```graphql
query {
  links(last: 3) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Query the objects from position 21 to position 27 (seeking backward)_:

![](https://i.imgur.com/iSl9Y07.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    last: 7,
    skip: 3
  })
```

```graphql
query {
  links(
    last: 7
    skip: 3
  ) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Query the first 3 objects after the object with `cixnen24p33lo0143bexvr52n` as `id`_:

![](https://i.imgur.com/InYSSkQ.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    first: 3,
    after: "cixnen24p33lo0143bexvr52n"
  })
```

```graphql
query {
  links(
    first: 3
    after: "cixnen24p33lo0143bexvr52n"
  ) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Query the first 5 objects after the object with `cixnen24p33lo0143bexvr52n` as `id` and skipping 3 objects_:

![](https://i.imgur.com/u4WEAJv.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    first: 5,
    after: "cixnen24p33lo0143bexvr52n",
    skip: 3
  })
```

```graphql
query {
  links(
    first: 5
    after: "cixnen24p33lo0143bexvr52n"
    skip: 3
  ) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Query the last 5 objects before the object with `cixnen24p33lo0143bexvr52n` as `id`_:

![](https://i.imgur.com/306eghw.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    last: 5,
    before: "cixnen24p33lo0143bexvr52n"
  })
```

```graphql
query {
  links(
    last: 5
    before: "cixnen24p33lo0143bexvr52n"
  ) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

_Query the last 3 nodes before the node with cixnen24p33lo0143bexvr52n as id and skipping 5 nodes_:

![](https://i.imgur.com/iZGUiHJ.png)

<Code languages={["JavaScript", "GraphQL"]}>

```js
const links = await prisma
  .links({
    last: 3,
    before: "cixnen24p33lo0143bexvr52n",
    skip: 5
  })
```

```graphql
query {
  links(
    last: 3 
    before: "cixnen24p33lo0143bexvr52n"
    skip: 5
  ) {
    id
    createdAt
    description
    url
  }
}
```

</Code>

## Aggregations

You can submit aggregation queries via [connection queries](vw4d#connection-relay-pagination--aggregations). The following aggregation functions are supported:

- `count`: Counts the number of objects in a list
- `avg` (_coming soon_): Computes the average of a list of numbers.
- `median` (_coming soon_): Computes the median of a list of numbers. 
- `max` (_coming soon_): Returns the greatest element of a list of numbers.
- `min` (_coming soon_): Returns the smallest element of a list of numbers.
- `sum` (_coming soon_): Computes the sum of a list of numbers.

> See [this](https://github.com/prisma/prisma/issues/1312) GitHub issue to learn more about the upcoming aggregation functions.

### Examples

_Count the number of link objects_:

<Code languages={["JavaScript", "GraphQL"]}>

```js
const linkCount = await prisma
  .linksConnection()
  .aggregate()
  .count()
```

```graphql
query {
  linksConnection {
    aggregate {
      count
    }
  }
}
```

</Code>
